﻿package com.mixmedia.net {
	import flash.events.EventDispatcher;
	import flash.events.StatusEvent;
	import flash.net.LocalConnection;	

	/**
	 * @author colin
	 */
	final public class LocalConnectionEvt extends EventDispatcher{
		private var base:LocalConnection;
		private var registeredConnections:Array;
		private var methods:Object;
		private var connName:String;
		private var id : String;
		
		private const METHOD_REGISTER:String = '__register';
		private const METHOD_REMOVE:String   = '__removeConn';
	
		public const EVENT_ERROR:String = 'error';
		public const EVENT_STATUS:String = 'status';
	
		public function LocalConnectionEvt(){
			trace('NOT TEST');
			base = new LocalConnection();
			base.addEventListener(StatusEvent.STATUS, onStatus);
			
			registeredConnections=new Array();
			methods = {};	
		}
	
		public function connect(connectionName : String) : Boolean{
			close();
			connName = connectionName;
	
			if(base.connect(connectionName)==true){
				id = connectionName;
				base[METHOD_REGISTER] = registerConnection;
				base[METHOD_REMOVE]   = removeConnection;
				return true;
			}
			return setupSecondaryConnection();
		};
	
		public function send(connectionName : String, methodName : String, args : Object) : Boolean{
			return base.send(connectionName, methodName, args);
		};
		
		public function close() : void{
			base.send(connName,METHOD_REMOVE,id);
			connName = null;
			base.close();
		};
		
		public function domain() : String{
			return base.domain;
		};

		public function allowDomain(domain : String) : Boolean{
			return base.allowDomain(domain);
		};
	
		public function allowInsecureDomain(domain : String) : Boolean{
			return base.allowDomain(domain);
		};
	
		public function addMethod(methodName:String,fnt:Function):void{
			var ins:LocalConnectionEvt = this;
			base[methodName] = function():void{
				ins.broadcastToChildConnections(methodName,arguments);
			};
			methods[methodName] = fnt;
		}
	
		private function onStatus(e:StatusEvent):void{
			dispatchEvent(e);
		}

		private function broadcastToChildConnections(methodName:String,args:Array):void{
			for(var i:Number=0;i<registeredConnections.length;i++){
				var lcs:LocalConnection = new LocalConnection();
				lcs.send(registeredConnections[i],methodName,args);
			}
			methods[methodName](args);
		}
		
		private function setupSecondaryConnection():Boolean{
			var timeStamp:Date = new Date();
			id = connName+timeStamp.getTime()+String(Math.random()).split(".")[1];
			base.send(connName,METHOD_REGISTER,id);
			return base.connect(id);
		}
	
		private function registerConnection(connectionName:String):void{
			removeConnection(connectionName);
			registeredConnections.push(connectionName);
		}
		
		private function removeConnection(connectionName:String):void{
			var lcTest:LocalConnection = new LocalConnection();
			for(var i:Number = 0;i<registeredConnections.length;i++){
				var isConnectEmpty:Boolean = lcTest.connect(registeredConnections[i]);
				lcTest.close();
				if((registeredConnections[i]==connectionName)||(isConnectEmpty==true)){
					registeredConnections.splice(i,1);
					i--;
				}
			}
		}
	}
}
